﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using System.Collections;

namespace DemoPatternAuthentication
{
    public partial class Form1 : Form
    {
        //startPattern contains click event
        //when click first time startPattern=true
        //when click second time startPattern=false
        public static bool startPattern = false;

        /// <summary>
        /// pattern contain node user hover 
        /// </summary>
        public static string pattern = "";
        
        public Form1()
        {
            InitializeComponent();
        }

        // pattern 1
        private void pic_Pattern1_MouseHover(object sender, EventArgs e)
        {
            MouseHorverAction(pic_Pattern1, "1");
        }
        private void pic_Pattern1_MouseLeave(object sender, EventArgs e)
        {
            MouseLeaveAction(pic_Pattern1,"1");
        }
        private void pic_Pattern1_MouseClick(object sender, MouseEventArgs e)
        {
            MouseClickAction(pic_Pattern1, "1");
        }

        // pattern 2
        private void pic_Pattern2_MouseHover(object sender, EventArgs e)
        {
            MouseHorverAction(pic_Pattern2, "2");
        }
        private void pic_Pattern2_MouseLeave(object sender, EventArgs e)
        {
            MouseLeaveAction(pic_Pattern2,"2");
        }
        private void pic_Pattern2_MouseClick(object sender, MouseEventArgs e)
        {
            MouseClickAction(pic_Pattern2, "2");
        }

        // pattern 3
        private void pic_Pattern3_MouseHover(object sender, EventArgs e)
        {
            MouseHorverAction(pic_Pattern3, "3");
        }
        private void pic_Pattern3_MouseLeave(object sender, EventArgs e)
        {
            MouseLeaveAction(pic_Pattern3,"3");
        }
        private void pic_Pattern3_MouseClick(object sender, MouseEventArgs e)
        {
            MouseClickAction(pic_Pattern3, "3");
        }

        // pattern 4
        private void pic_Pattern4_MouseHover(object sender, EventArgs e)
        {
            MouseHorverAction(pic_Pattern4, "4");
        }
        private void pic_Pattern4_MouseLeave(object sender, EventArgs e)
        {
            MouseLeaveAction(pic_Pattern4,"4");
        }
        private void pic_Pattern4_MouseClick(object sender, MouseEventArgs e)
        {
            MouseClickAction(pic_Pattern4, "4");
        }

        // pattern 5
        private void pic_Pattern5_MouseHover(object sender, EventArgs e)
        {
            MouseHorverAction(pic_Pattern5, "5");
        }
        private void pic_Pattern5_MouseLeave(object sender, EventArgs e)
        {
            MouseLeaveAction(pic_Pattern5,"5");
        }
        private void pic_Pattern5_MouseClick(object sender, MouseEventArgs e)
        {
            MouseClickAction(pic_Pattern5, "5");
        }

        // pattern 6
        private void pic_Pattern6_MouseHover(object sender, EventArgs e)
        {
            MouseHorverAction(pic_Pattern6, "6");
        }
        private void pic_Pattern6_MouseLeave(object sender, EventArgs e)
        {
            MouseLeaveAction(pic_Pattern6,"6");
        }
        private void pic_Pattern6_MouseClick(object sender, MouseEventArgs e)
        {
            MouseClickAction(pic_Pattern6, "6");
        }

        // pattern 7
        private void pic_Pattern7_MouseHover(object sender, EventArgs e)
        {
            MouseHorverAction(pic_Pattern7, "7");
        }
        private void pic_Pattern7_MouseLeave(object sender, EventArgs e)
        {
            MouseLeaveAction(pic_Pattern7,"7");
        }
        private void pic_Pattern7_MouseClick(object sender, MouseEventArgs e)
        {
            MouseClickAction(pic_Pattern7, "7");
        }

        // pattern 8
        private void pic_Pattern8_MouseHover(object sender, EventArgs e)
        {
            MouseHorverAction(pic_Pattern8, "8");
        }
        private void pic_Pattern8_MouseLeave(object sender, EventArgs e)
        {
            MouseLeaveAction(pic_Pattern8,"8");
        }
        private void pic_Pattern8_MouseClick(object sender, MouseEventArgs e)
        {
            MouseClickAction(pic_Pattern8, "8");
        }

        // pattern 9
        private void pic_Pattern9_MouseHover(object sender, EventArgs e)
        {
            MouseHorverAction(pic_Pattern9, "9");
        }
        private void pic_Pattern9_MouseLeave(object sender, EventArgs e)
        {
            MouseLeaveAction(pic_Pattern9,"9");
        }
        private void pic_Pattern9_MouseClick(object sender, MouseEventArgs e)
        {
            MouseClickAction(pic_Pattern9, "9");
        }

        ///<summary>
        ///show error when login failed, the pic in pattern will be change color to red
        ///</summary>
        public void ShowErrorPattern()
        {
            try
            {
                if (!pattern.Trim().Equals(""))
                {
                    for (int i = 0; i < pattern.Length; i++)
                    {
                        string node = pattern.ElementAt(i).ToString();
                        switch (node)
                        {
                            case "1":
                                ChangeFailedStatus(pic_Pattern1);
                                break;
                            case "2":
                                ChangeFailedStatus(pic_Pattern2);
                                break;
                            case "3":
                                ChangeFailedStatus(pic_Pattern3);
                                break;
                            case "4":
                                ChangeFailedStatus(pic_Pattern4);
                                break;
                            case "5":
                                ChangeFailedStatus(pic_Pattern5);
                                break;
                            case "6":
                                ChangeFailedStatus(pic_Pattern6);
                                break;
                            case "7":
                                ChangeFailedStatus(pic_Pattern7);
                                break;
                            case "8":
                                ChangeFailedStatus(pic_Pattern8);
                                break;
                            case "9":
                                ChangeFailedStatus(pic_Pattern9);
                                break;
                        }
                    }
                    System.Threading.Thread.Sleep(1000);
                    RefreshScreen();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.StackTrace);
            }
        }

        public void RefreshScreen()
        {
            pic_Pattern1.ImageLocation = Common.Common.GetImageOffStatus();
            pic_Pattern2.ImageLocation = Common.Common.GetImageOffStatus();
            pic_Pattern3.ImageLocation = Common.Common.GetImageOffStatus();
            pic_Pattern4.ImageLocation = Common.Common.GetImageOffStatus();
            pic_Pattern5.ImageLocation = Common.Common.GetImageOffStatus();
            pic_Pattern6.ImageLocation = Common.Common.GetImageOffStatus();
            pic_Pattern7.ImageLocation = Common.Common.GetImageOffStatus();
            pic_Pattern8.ImageLocation = Common.Common.GetImageOffStatus();
            pic_Pattern9.ImageLocation = Common.Common.GetImageOffStatus();
            Graphics graphics = this.CreateGraphics();
            graphics.Clear(Color.White);
        }

        public void LoginSuccess()
        {
            MessageBox.Show("Ban da dang nhap thanh cong", "Successful.");
            RefreshScreen();
        }

        public void MouseClickAction(PictureBox pic, string number)
        {
            if (startPattern)
            {
                startPattern = false;
                if (Common.Common.LoginHandler(pattern))
                {
                    LoginSuccess();
                }
                else
                {
                    ShowErrorPattern();
                }
                pattern = "";
            }
            else
            {
                startPattern = true;
                pattern = pattern + number;
                pic.ImageLocation = Common.Common.GetImageOnStatus();
                pic.Load();
                Application.DoEvents();
                pic.WaitOnLoad = true;
            }
        }

        public void MouseHorverAction(PictureBox pic, string number)
        {
            if (startPattern)
            {
                if (pic.ImageLocation != Common.Common.GetImageOnStatus())
                {
                    //connect 2 pic by line
                    ConnectPic(pic, number);
                    pattern = pattern + number;
                    pic.ImageLocation = Common.Common.GetImageOnStatus();
                    pic.Load();
                }
            }
        }

        public void ProcessSpecialCase(int lastNode, int currentNode)
        {
            if ((lastNode == 2 && currentNode ==8) || (lastNode == 8 && currentNode ==2)
                || (lastNode == 4 && currentNode == 6) || (lastNode == 6 && currentNode == 4))
            {
                // just only node 5 in this case
                pic_Pattern5.ImageLocation = Common.Common.GetImageOnStatus();
                if (!pattern.Contains("5"))
                    pattern += "5";
            }
        }

        public void MouseLeaveAction(PictureBox pic, string number)
        {
            if (startPattern)
            {
                if (!pattern.Equals(""))
                {
                    if (!pattern.Contains(number))
                    {
                        //connect 2 pic by line
                        ConnectPic(pic, number);
                        pattern += number;
                    }
                }
                if (pic.ImageLocation != Common.Common.GetImageOnStatus())
                {
                    pic.ImageLocation = Common.Common.GetImageOnStatus();
                    pic.WaitOnLoad = true;
                }

            }
        }

        public void ConnectPic(PictureBox pic, string number)
        {
            //connect 2 pic by line
            if (GetLastNode() != null)
            {
                ConnectPicByLine(GetLastNode(), pic);
                Application.DoEvents();
                pic.WaitOnLoad = true;

                //handle in case user input from 1 to 7, or 1 to 9....
                //must high light the middle node
                if (!number.Equals("") && !number.Equals("5"))
                {
                    string lastStringNode = GetLastStringNode();
                    if (!lastStringNode.Equals("") && !lastStringNode.Equals("5"))
                    {
                        int lastNode = Int32.Parse(lastStringNode);
                        int currentNode = Int32.Parse(number);
                        if (lastNode % 2 == 0 && currentNode % 2 == 0)
                        {
                            ProcessSpecialCase(lastNode, currentNode);
                        }
                        else
                        {
                            double middleNode = (lastNode + currentNode) / 2.0;
                            if (middleNode % 2 == 0 || middleNode == 5)
                            {
                                GetNodeFromString(middleNode.ToString()).ImageLocation = Common.Common.GetImageOnStatus();
                                if (!pattern.Contains(middleNode.ToString()))
                                    pattern += middleNode.ToString();
                            }
                        }
                    }

                }
            }
        }

        public void ChangeFailedStatus(PictureBox pic)
        {
            pic.ImageLocation = Common.Common.GetImageFailedStatus();
            pic.Load();
            Application.DoEvents();
            pic.WaitOnLoad = true;
        }

        public void ConnectPicByLine(PictureBox pic1, PictureBox pic2)
        {
            Point point1 = new Point((pic1.Right - pic1.Width/2), (pic1.Bottom - pic1.Height/2));
            Point point2 = new Point((pic2.Right - pic2.Width / 2), (pic2.Bottom - pic2.Height / 2));
            Graphics graphic = this.CreateGraphics();
            Pen pen = new Pen(Color.DarkGray, 10);
            graphic.DrawLine(pen, point1, point2);
            pen.Dispose();
            graphic.Dispose();
        }

        public string GetLastStringNode()
        {
            if (!pattern.Equals(""))
            {
                string node = pattern.ElementAt(pattern.Length - 1).ToString();
                return node;
            }
            else
                return "";
        }
        public PictureBox GetLastNode()
        {
            string lastNode = GetLastStringNode();
            if(!lastNode.Equals(""))
            {
                return GetNodeFromString(lastNode);
            }
            else
            {
                return null;
            }
        }

        public PictureBox GetNodeFromString(string node)
        {
            if (!node.Equals(""))
            {
                switch (node)
                {
                    case "1":
                        return pic_Pattern1;
                    case "2":
                        return pic_Pattern2;
                    case "3":
                        return pic_Pattern3;
                    case "4":
                        return pic_Pattern4;
                    case "5":
                        return pic_Pattern5;
                    case "6":
                        return pic_Pattern6;
                    case "7":
                        return pic_Pattern7;
                    case "8":
                        return pic_Pattern8;
                    case "9":
                        return pic_Pattern9;
                    default:
                        return null;
                }
            }
            else
                return null;
        }
    }
}
